package com.yeskery.nut.bind;

import com.yeskery.nut.util.StringUtils;

import java.math.BigDecimal;

/**
 * 合适值帮助类
 * @author sprout
 * 2022-06-11 16:01
 */
public class FitValueHelper {

    /** 实例对象 */
    private static final FitValueHelper INSTANCE = new FitValueHelper();

    /**
     * 私有化构造方法
     */
    private FitValueHelper() {
    }

    /**
     * 获取实例对象
     * @return 实例对象
     */
    public static FitValueHelper getInstance() {
        return INSTANCE;
    }

    /**
     * 获取适合的参数值
     * @param name 参数名称
     * @param value 参数字符串值
     * @param clazz 参数类型
     * @return 适合的参数值
     */
    public BindObject getFitParamValue(String name, String value, Class<?> clazz) {
        boolean emptyValue = StringUtils.isEmpty(value);
        try {
            if (String.class == clazz) {
                return new BindObject(value, emptyValue);
            } else if (boolean.class == clazz) {
                return new BindObject(!emptyValue && Boolean.parseBoolean(value), emptyValue);
            } else if (Boolean.class == clazz) {
                return new BindObject(emptyValue ? null : Boolean.valueOf(value), emptyValue);
            } else if (byte.class == clazz) {
                return new BindObject(emptyValue ? (byte) 0 : Byte.parseByte(value), emptyValue);
            } else if (Byte.class == clazz) {
                return new BindObject(emptyValue ? null : Byte.valueOf(value), emptyValue);
            } else if (short.class == clazz) {
                return new BindObject(emptyValue ? (short) 0 : Short.parseShort(value), emptyValue);
            } else if (Short.class == clazz) {
                return new BindObject(emptyValue ? null : Short.valueOf(value), emptyValue);
            } else if (int.class == clazz) {
                return new BindObject(emptyValue ? 0 : Integer.parseInt(value), emptyValue);
            } else if (Integer.class == clazz) {
                return new BindObject(emptyValue ? null : Integer.valueOf(value), emptyValue);
            } else if (long.class == clazz) {
                return new BindObject(emptyValue ? 0L : Long.parseLong(value), emptyValue);
            } else if (Long.class == clazz) {
                return new BindObject(emptyValue ? null : Long.valueOf(value), emptyValue);
            } else if (float.class == clazz) {
                return new BindObject(emptyValue ? 0.0F : Float.parseFloat(value), emptyValue);
            } else if (Float.class == clazz) {
                return new BindObject(emptyValue ? null : Float.valueOf(value), emptyValue);
            } else if (double.class == clazz) {
                return new BindObject(emptyValue ? 0.0 : Double.parseDouble(value), emptyValue);
            } else if (Double.class == clazz || Number.class == clazz) {
                return new BindObject(emptyValue ? null : Double.valueOf(value), emptyValue);
            } else if (BigDecimal.class == clazz) {
                return new BindObject(emptyValue ? null : new BigDecimal(value), emptyValue);
            }
        } catch (Exception e) {
            throw new DataBindException("Invalid Parameter [" + name + "] For Value [" + value + "]", e);
        }
        return new BindObject(null, true);
    }

    /**
     * 判断是否是基础类型的class
     * @param clazz 参数类型
     * @return 是否是基础类型的class
     */
    public boolean isBasicTypeClass(Class<?> clazz) {
        return String.class == clazz || boolean.class == clazz || Boolean.class == clazz || isNumberBasicTypeClass(clazz);
    }

    /**
     * 判断是否是数字类型的class
     * @param clazz 参数类型
     * @return 是否是数字类型的class
     */
    public boolean isNumberBasicTypeClass(Class<?> clazz) {
        return byte.class == clazz || Byte.class == clazz || short.class == clazz || Short.class == clazz || int.class == clazz
                || Integer.class == clazz || long.class == clazz || Long.class == clazz || float.class == clazz
                || Float.class == clazz || double.class == clazz || Double.class == clazz || Number.class == clazz
                || BigDecimal.class == clazz;
    }

    /**
     * 获取通用的参数类型名称
     * @param clazz 参数类型
     * @return 适合的参数类型名称
     */
    public String getCommonBasicTypeName(Class<?> clazz) {
        if (String.class == clazz) {
            return "string";
        } else if (boolean.class == clazz || Boolean.class == clazz) {
            return "boolean";
        }else if (isNumberBasicTypeClass(clazz)) {
            return "number";
        }
        return "unknown";
    }
}
